package top.yekongle.feature.java8.function;

import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.UnaryOperator;

public class GeneralFunction {

    public static void main(String[] args) {
        //new GeneralFunction().combineAndOrFunction();
    }

    void binaryOperator() {
        BinaryOperator<Long> binaryOperator = (a, b) -> a + b;
        binaryOperator.apply(1L, 1L);
    }

    void combineAndOrFunction () {
        Predicate<String> startsWithA = (text) -> text.startsWith("A");

        Predicate<String> endsWithX = (text) -> text.endsWith("X");

        Predicate<String> startsWithAAndEngWithX = startsWithA.and(endsWithX);

        Predicate<String> startsWithAOrEndWithX1 = startsWithA.or(endsWithX);

        boolean result1 = startsWithAAndEngWithX.test("ABC");
        boolean result2 = startsWithAOrEndWithX1.test("ABC");

        System.out.println("result1: " + result1 + ", result2: " + result2);
    }

    void combineComposeFunctionBad() {
        Function<String, Integer> function1 = (value) -> Integer.valueOf(value);

        Function<Integer, String> function2 = (num) -> num.toString();

        Function function3 = function1.compose(function2);

        // WIll occur error, function2 accept Integer, but input String
        function3.apply("ABC");
    }

    void combineComposeFunctionGood() {
        Function<String, Integer> function1 = (value) -> Integer.valueOf(value);

        Function<Integer, String> function2 = (num) -> num.toString();

        Function<Integer, Integer> function3 = function1.compose(function2);
    }

    void combineAndThenFunction() {
        Function<Integer, Integer> function1 = (value) -> Integer.valueOf(value);

        Function<Integer, String> function2 = (num) -> num.toString();

        Function<Integer, String> function3 = function1.andThen(function2);
    }

    class PredicateA implements Predicate<String>{

        @Override
        public boolean test(String text) {
            return text.startsWith("A");
        }

        @Override
        public Predicate<String> and(Predicate<? super String> other) {
            return (text) -> this.test(text) && other.test(text);
        }
    }

    class PredicateB implements Predicate<String>{

        @Override
        public boolean test(String text) {
            return text.startsWith("X");
        }
    }

    class PredicateC implements Predicate<String>{

        @Override
        public boolean test(String text) {
            return text.startsWith("X");
        }
    }


    class Test implements UnaryOperator {

        @Override
        public Object apply(Object o) {
            return null;
        }

        @Override
        public Function andThen(Function after) {
            return null;
        }

        @Override
        public Function compose(Function before) {
            return null;
        }
        }
}
